package com.mhy.utils;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Environment;
import android.view.View;

import java.io.File;
import java.io.FileOutputStream;

/**
 * Author:     Mahongtyin
 * Date:       2019/11/5 17:13
 * Copyrights: mhy.work@foxmail.com
 * Description:
 */
public class View2Bitmap {
    //    第一种
//    先看通过 DrawingCache
//    方法来截取普通的view，获取它的视图（Bitmap）。
//    这个方法适用于view 已经显示在界面上了，
//    可以获得view 的宽高实际大小，
//    进而通过DrawingCache 保存为bitmap。
    private Bitmap createBitmap(View view) {
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
    }

//
//    第二种
//    但是 如果要截取的view
//    没有在屏幕上显示完全的，
//    例如要截取的是超过一屏的 scrollview ，通过上面这个方法是获取不到bitmap的，需要使用下面方法，
//    传的view 是scrollview
//    的子view（LinearLayout）等，当然完全显示的view（第一种情况的view）也可以使用这个方法截取。

    public Bitmap createBitmap2(View v) {
        Bitmap bmp = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);
//        c.drawColor(Color.WHITE);
        /** 如果不设置canvas画布为白色，则生成透明 */
        v.draw(c);
        return bmp;
    }

//    第三种
//    还有一种 是view完全没有显示在界面上，
//    通过inflate 转化的view，
//    这时候通过 DrawingCache
//    是获取不到bitmap 的，
//    也拿不到view 的宽高，以上两种方法都是不可行的。第三种方法通过measure、
//    layout 去获得view
//    的实际尺寸。

    public Bitmap createBitmap3(View v, int width, int height) {
        //测量使得view指定大小
        int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
        int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
        v.measure(measuredWidth, measuredHeight);
        //调用layout方法布局后，可以得到view的尺寸大小
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        Bitmap bmp = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);
//        c.drawColor(Color.WHITE);
        v.draw(c);
        return bmp;
    }

    public Bitmap createBitmap4(View view) {
//    View view = LayoutInflater.from(this).inflate(R.layout.view_inflate, null, false);
        //这里传值屏幕宽高，得到的视图即全屏大小
        return createBitmap3(view, getScreenWidth(), getScreenHeight());
//    另外写了个简易的保存图片的方法，方便查看效果的。
    }
    public static int getScreenWidth() {
        return Resources.getSystem().getDisplayMetrics().widthPixels;
    }

    public static int getScreenHeight() {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }
    /**
     * 返回路径
     *
     * @param bitmap
     * @param fileName
     * @return
     */
    public static String saveBitmap(Bitmap bitmap, String fileName) {
        FileOutputStream fos;
        String locUrl = "";
        try {
            File root = Environment.getExternalStorageDirectory();
//      File file = new File(root.getAbsolutePath() + "/selector/crop/"+fileName);
            File file = new File(root, fileName);
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.flush();
            fos.close();
            locUrl = root + "/" + fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return locUrl;
    }

    public static String saveBitmap2(Bitmap bitmap, String fileName) {
        FileOutputStream fos;
        String locUrl = "";
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            // 判断是否可以对SDcard进行操作
            // 获取SDCard指定目录下   TODO 保存相册 再改路径 DCIM
            String sdCardDir = Environment.getExternalStorageDirectory() + "/selector/crop/";
            File dirFile = new File(sdCardDir);  //目录转化成文件夹
            if (!dirFile.exists()) {                //如果不存在，那就建立这个文件夹
                dirFile.mkdirs();
            }
            // 文件夹有啦，就可以保存图片啦
            File file = new File(sdCardDir, fileName);
            // 在SDcard的目录下创建图片文,以当前时间为其命名
        try {
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.flush();
            fos.close();
            locUrl = sdCardDir  + fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }}
        return locUrl;
    }


    private static Bitmap viewToBitmap1(View v) {
        //要求view已经经过layout在界面上显示
        v.setDrawingCacheEnabled(true);
        v.buildDrawingCache();
        Bitmap screenshot = v.getDrawingCache();
        v.setDrawingCacheEnabled(false);
        return screenshot;
    }

    private static Bitmap viewToBitmap2(View v) {
        Bitmap screenshot;
        screenshot = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_4444);
        Canvas canvas = new Canvas(screenshot);
        v.draw(canvas);
        return screenshot;
    }


/**
 * ARGB_8888：四个通道都是8位，每个像素占用4个字节，图片质量是最高的，但是占用的内存也是最大的；
 * ARGB_4444：四个通道都是4位，每个像素占用2个字节，图片的失真比较严重；
 * RGB_565：没有A通道，每个像素占用2个字节，图片失真小，但是没有透明度；
 * ALPHA_8：只有A通道，每个像素占用1个字节大大小，只有透明度，没有颜色值。
 *
 * 作者：druidZ
 * 链接：https://juejin.im/post/5bdc0538e51d45052468e844
 * 来源：掘金
 * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
 */
    /**
     * view转bitmap
     */

    //将要存为图片的view传进来 生成bitmap对象
    public static Bitmap createViewBitmap(View v) {
        Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
//        canvas.drawColor(Color.WHITE);
        v.draw(canvas);
        return bitmap;
    }

    public static Bitmap viewConversionBitmap(View v) {
        int w = v.getWidth();
        int h = v.getHeight();

        Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);
//        c.drawColor(Color.WHITE);
        /** 如果不设置canvas画布为白色，则生成透明 */
        v.layout(0, 0, w, h);
        v.draw(c);
        return bmp;
    }
}
